package operations;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Arrays;
import java.util.Map;

import util.Randomness;

import model.CUT;
import model.ConstantDeclared;
import model.StatementKind;
import model.TestClusterBuilder;

public class AssignConstant extends Operation{
	private final Class<?> declaringClass;
	private final Class<?> cType;
	private  String ref;
	private final Field value;
	public AssignConstant(Class<?> declaringClass,String ref,Class<?> cType, Field value) {
		this.declaringClass=declaringClass;
		this.cType=cType;
		this.ref = ref;
		this.value = value;
	}
	

	public Class<?> getcType() {
		return cType;
	}
	public Class<?> getDeclaringClass() {
		return declaringClass;
	}
	public  String  getRefrence(){
		return this.ref;		
	}
	public  void  setRefrence(String ref_){
		 this.ref=ref_;		
	}

	public  Field  getValue(){
		return this.value;		
	}

	public static AssignConstant generate(CUT cut,TestClusterBuilder TestCluster){
//		if(cut.getClazz().equals("java.util.Locale"))
//			System.out.println("AssignConstant.generate: "+cut.getClazz() );
		Map<String, String[]> refFactory = TestCluster.getRefFactory();
		ConstantDeclared[]  constants=cut.getConstants();
		List <ConstantDeclared> constantsList=Arrays.asList(constants);
		if(constantsList.size()==0) return null;
		ConstantDeclared constant = constantsList.get(Randomness.nextRandomInt(constantsList.size()));
		Class<?> cType=constant.getOutputType();
		Field value=constant.getConstant();
		String 	ref = getReference(constant.getOutputType().getName(),refFactory);
		if( ValuesGenerator.getBoolean(Operation.SET_TO_NULL))
			return new AssignConstant(cut.getClazz(),ref,cType,null);
		if(ref!=null)
			return new AssignConstant(cut.getClazz(),ref,cType,value);
		return null;
	
	}
	public static AssignConstant recommendedgenerate(Class<?> clz,StatementKind constr, TestClusterBuilder TestCluster){
		Map<String, String[]> refFactory = TestCluster.getRefFactory();
		ConstantDeclared constant=(ConstantDeclared)constr;

		Class<?> cType=constant.getOutputType();
		Field value=constant.getConstant();
		String 	ref = getReference(constant.getOutputType().getName(),refFactory);
		if( ValuesGenerator.getBoolean(Operation.SET_TO_NULL))
			return new AssignConstant(clz,ref,cType,null);
		if(ref!=null)
			return new AssignConstant(clz,ref,cType,value);
	
		return null;
	}
	

	@Override
	public Operation clone() {
		final AssignConstant clone = new AssignConstant(declaringClass,ref,cType, value);

		return clone;
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		
		sb.append("  "+ref+ " = ");
		if(value == null)  sb.append("null".toString() );
		else	
			sb.append(value.getDeclaringClass().getName()+"." + value.getName());
		
		return sb.toString();

	}


}
